from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
from django.core.cache import cache
from django.conf import settings

import json, jwt, time


def need_login(request):
    need_verification_path = [
        "/api/user/login",
        "/api/user/logout",
        "/api/user/resetPass",
        "/api/admin/login",
        "/api/admin/logout",
        "/api/admin/login/captcha",
        "/api/user/register",
        "/api/user/session",
        "/api/chat/history",
        "/api/chat/detail",
        "/api/chat/list",
        "/api/role/list",
        "/api/model/list",
        "/api/mj/imgWall",
        "/api/mj/client",
        "/api/mj/notify",
        "/api/invite/hits",
        "/api/sd/imgWall",
        "/api/sd/client",
        "/api/dall/imgWall",
        "/api/dall/client",
        "/api/config/get",
        "/api/product/list",
        "/api/menu/list",
        "/api/markMap/client"
    ]

    re_path = request.path_info

    if re_path in need_verification_path:
        return True
    elif re_path.startswith((
        "/api/test",
        "/api/function/",
        "/api/sms/",
        "/api/captcha/",
        "/api/payment/",
        "/static/",
        "/media/"
    )):
        return True
    else:
        return False


# 登陆认证中间件
class AuthenticationMiddleware(MiddlewareMixin):
    def process_request(self, request):
        isAdminApi = False
        if "/api/admin/" in request.path_info:
            isAdminApi = True
            tokenString = request.META.get("HTTP_ADMIN_AUTHORIZATION")
        elif request.path_info == "/api/chat/new":
            tokenString = request.GET.get("token")
        else:
            tokenString = request.META.get("HTTP_AUTHORIZATION")

        # if not need_login(request):
        #     return

        if tokenString is None or not tokenString:
            # 判断如果是不需要登陆的url 就直接放行了。要是需要登陆的就返回 没有授权
            if need_login(request):
                return
            else:
                res_mes = {
                    "code": 1,
                    "message": "登陆已过期，请重新登录！"
                }
                res_mes_json = json.dumps(res_mes, ensure_ascii=False)
                return HttpResponse(res_mes_json)
            
        # 解密token
        try:
            de_payload_json = jwt.decode(tokenString, settings.MY_TOKEN_CONF['SECRETKEY'], algorithms=['HS256'])
        except Exception as e:
            res_mes = {
                "code": 400,
                "message": "签名验证失败"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # payload_json = {
        #     "user_id": re_user_obj.id,
        #     "username": re_user_obj.username,
        #     "expired": expired_time,
        #     "isadminapi": True
        # }
        # 验证签名里面的内容
        if not "user_id" in de_payload_json and not "expired" in de_payload_json and not need_login(request):
            res_mes = {
                "code": 400,
                "message": "签名验证失败"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # 从redis获取token 看是否有效token
        if isAdminApi and not need_login(request):
            mes_key = "admin/%s" % de_payload_json['user_id']
        else:
            mes_key = "users/%s" % de_payload_json['user_id']

        redis_mes_token = cache.get(mes_key)
        if redis_mes_token is None and not need_login(request):
            res_mes = {
                "code": 400,
                "message": "token无效"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # 判断token是否失效
        now_time = time.time()
        expired_time = de_payload_json['expired']
        if expired_time < now_time and not need_login(request):
            res_mes = {
                "code": 400,
                "message": "token失效!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # 设置request属性
        if isAdminApi and not need_login(request):
            # admin
            request.session["LOGIN_USER_ID_ADMIN"] = de_payload_json['user_id']
        else:
            # user
            request.session["LOGIN_USER_ID"] = de_payload_json['user_id']
        # print("我走到了中间件的最后", request.session.keys())
        # return self.get_response(request)

